home *** CD-ROM | disk | FTP | other *** search
Text File | 1997-01-02 | 7.1 KB | 301 lines | [TEXT/????] |
- //
- // MEMSTRM.CPP
- //
- // Copyright (C) Microsoft Corporation, 1996
- //
- // Implementation of a Netscape stream notification object that "writes" data
- // to a memory buffer. This memory buffer can be utilized externally with the
- // IStream interface.
- //
- // This has been broken up into CMemoryStreamNotify which does the simple
- // copy-into-memory-buffer logic. CMemoryOleStreamNotify implements an IStream
- // interface on top of this class.
- //
-
- #include "headers.h"
-
- //
- // CMemoryStreamNotify::~CMemoryStreamNotify
- //
-
- CMemoryStreamNotify::~CMemoryStreamNotify()
- {
- if (m_pStream != NULL)
- CoTaskMemFree(m_pStream);
- }
-
- //
- // CMemoryStreamNotify::OnWrite
- //
-
- int32
- CMemoryStreamNotify::OnWrite(NPStream *stream, int32 offset, int32 len, void
- *buffer)
- {
- #pragma unused (stream, offset)
- LPVOID pNewStream;
- int32 BytesWritten;
-
- if (m_pStream == NULL) {
- pNewStream = (LPVOID) CoTaskMemAlloc(len);
- } else {
- pNewStream = (LPVOID) CoTaskMemRealloc(m_pStream, m_StreamLength + len);
- }
-
- if (pNewStream != NULL) {
- BlockMove(buffer, ((LPBYTE) pNewStream + m_StreamLength), len);
- m_pStream = pNewStream;
- m_StreamLength += len;
- BytesWritten = len;
- } else {
- // Returning a negative value causes the stream to error out and be
- // destroyed.
- BytesWritten = -1;
- }
-
- return BytesWritten;
- }
-
- //
- // CMemoryOleStreamNotify::IUnknown::QueryInterface
- //
-
- STDMETHODIMP
- CMemoryOleStreamNotify::QueryInterface(REFIID riid, LPVOID *ppvObj)
- {
- HRESULT hr;
- LPVOID pv;
-
- if (riid == IID_IUnknown || riid == IID_IStream) {
- pv = (LPVOID)(LPSTREAM) this;
- ++m_cRef;
- hr = ResultFromScode(S_OK);
- } else {
- pv = NULL;
- hr = ResultFromScode(E_NOINTERFACE);
- }
-
- *ppvObj = pv;
- return hr;
- }
-
- //
- // CMemoryOleStreamNotify::IUnknown::AddRef
- //
-
- STDMETHODIMP_(ULONG)
- CMemoryOleStreamNotify::AddRef(void)
- {
- return ++m_cRef;
- }
-
- //
- // CMemoryOleStreamNotify::IUnknown::Release
- //
-
- STDMETHODIMP_(ULONG)
- CMemoryOleStreamNotify::Release(void)
- {
- if (--m_cRef != 0)
- return m_cRef;
-
- delete this;
- return 0;
- }
-
- //
- // CMemoryOleStreamNotify::IStream::Read
- //
-
- STDMETHODIMP
- CMemoryOleStreamNotify::Read(void *pv, DWORD cb, LPDWORD pcbRead)
- {
- // Verify that we're not try to read more bytes than are available. If we
- // are, clip the actual number of bytes copied. The OLE32 memory stream
- // implementation doesn't return an error, so we won't either.
- if (((LONG) cb < 0) || (cb + (ULONG) m_SeekPosition > (ULONG) m_StreamLength)) {
- if (m_fAsyncStreamInProgress) {
- // Special case: if we're in the middle of streaming some data from
- // the network, return E_PENDING so that async binding works
- // correctly.
- // BUGBUG: Above if statement probably isn't adequate, review this.
- return ResultFromScode(E_PENDING);
- } else {
- cb = m_StreamLength - m_SeekPosition;
- }
- }
-
- if (cb > 0) {
- BlockMove((LPBYTE) m_pStream + m_SeekPosition, pv, cb);
- m_SeekPosition += cb;
- }
-
- if (pcbRead != NULL)
- *pcbRead = cb;
-
- return ResultFromScode(S_OK);
- }
-
- //
- // CMemoryOleStreamNotify::IStream::Write
- //
-
- STDMETHODIMP
- CMemoryOleStreamNotify::Write(void const *pv, DWORD cb, LPDWORD pcbWritten)
- {
- #pragma unused (pv, cb, pcbWritten)
- return ResultFromScode(STG_E_ACCESSDENIED);
- }
-
- //
- // CMemoryOleStreamNotify::IStream::Seek
- //
-
- STDMETHODIMP
- CMemoryOleStreamNotify::Seek(LARGE_INTEGER dlibMove, DWORD dwOrigin,
- ULARGE_INTEGER *plibNewPosition)
- {
- HRESULT hr = ResultFromScode(S_OK);
- LONG lMove = (LONG) dlibMove.LowPart;
-
- // Note that we don't care about dlibMove.HighPart. Checking the Win32
- // OLE sources, there implementation of a memory stream doesn't bother, so
- // if the reference implementation blows off the issue of 64-bit, then we
- // sure as hell can. In fact, the below was lifted from OLE.
- switch (dwOrigin) {
-
- case STREAM_SEEK_SET:
- if (lMove >= 0) {
- m_SeekPosition = lMove;
- } else {
- hr = ResultFromScode(STG_E_SEEKERROR);
- }
- break;
-
- case STREAM_SEEK_CUR:
- if (!(lMove < 0 && ((ULONG) -lMove) > (ULONG) m_SeekPosition)) {
- m_SeekPosition += lMove;
- } else {
- hr = ResultFromScode(STG_E_SEEKERROR);
- }
- break;
-
- case STREAM_SEEK_END:
- if (!(lMove < 0 && ((ULONG) -lMove) > (ULONG) m_StreamLength)) {
- m_SeekPosition += m_StreamLength + lMove;
- } else {
- hr = ResultFromScode(STG_E_SEEKERROR);
- }
- break;
-
- default:
- hr = ResultFromScode(STG_E_INVALIDFUNCTION);
- break;
- }
-
- if (plibNewPosition != NULL) {
- plibNewPosition->HighPart = 0;
- plibNewPosition->LowPart = m_SeekPosition;
- }
-
- return hr;
- }
-
- //
- // CMemoryOleStreamNotify::IStream::SetSize
- //
-
- STDMETHODIMP
- CMemoryOleStreamNotify::SetSize(ULARGE_INTEGER libNewSize)
- {
- #pragma unused (libNewSize)
- // We're a read-only stream, so there's no reason to resize our stream.
- return ResultFromScode(STG_E_INVALIDFUNCTION);
- }
-
- //
- // CMemoryOleStreamNotify::IStream::CopyTo
- //
-
- STDMETHODIMP
- CMemoryOleStreamNotify::CopyTo(LPSTREAM pstm, ULARGE_INTEGER cb, ULARGE_INTEGER
- *pcbRead, ULARGE_INTEGER *pcbWritten)
- {
- #pragma unused (pstm, cb, pcbRead, pcbWritten)
- // There's no good reason for this not to be implemented.
- return ResultFromScode(E_NOTIMPL);
- }
-
- //
- // CMemoryOleStreamNotify::IStream::Commit
- //
-
- STDMETHODIMP
- CMemoryOleStreamNotify::Commit(DWORD grfCommitFlags)
- {
- #pragma unused (grfCommitFlags)
- // We can always "commit" because it's not possible to write to the stream.
- return ResultFromScode(S_OK);
- }
-
- //
- // CMemoryOleStreamNotify::IStream::Revert
- //
-
- STDMETHODIMP
- CMemoryOleStreamNotify::Revert(void)
- {
- // We can always "revert" because it's not possible to write to the stream.
- return ResultFromScode(S_OK);
- }
-
- //
- // CMemoryOleStreamNotify::IStream::LockRegion
- //
-
- STDMETHODIMP
- CMemoryOleStreamNotify::LockRegion(ULARGE_INTEGER libOffset, ULARGE_INTEGER cb,
- DWORD dwLockType)
- {
- #pragma unused (libOffset, cb, dwLockType)
- return ResultFromScode(STG_E_INVALIDFUNCTION);
- }
-
- //
- // CMemoryOleStreamNotify::IStream::UnlockRegion
- //
-
- STDMETHODIMP
- CMemoryOleStreamNotify::UnlockRegion(ULARGE_INTEGER libOffset, ULARGE_INTEGER
- cb, DWORD dwLockType)
- {
- #pragma unused (libOffset, cb, dwLockType)
- return ResultFromScode(STG_E_INVALIDFUNCTION);
- }
-
- //
- // CMemoryOleStreamNotify::IStream::Stat
- //
-
- STDMETHODIMP
- CMemoryOleStreamNotify::Stat(STATSTG *pstatstg, DWORD grfStatFlag)
- {
- #pragma unused (grfStatFlag)
- // Implementation lifted from OLE32's memory stream.
- memset(pstatstg, 0, sizeof(*pstatstg));
- pstatstg->type = STGTY_STREAM;
- pstatstg->cbSize.LowPart = m_StreamLength;
- return ResultFromScode(S_OK);
- }
-
- //
- // CMemoryOleStreamNotify::IStream::Clone
- //
-
- STDMETHODIMP
- CMemoryOleStreamNotify::Clone(LPSTREAM *ppstm)
- {
- *ppstm = NULL;
- return ResultFromScode(E_NOTIMPL);
- }
-